home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / fpkpas92.zip / SRCRTL.ZIP / RTL / DOS / GO32V2 / CRT.PP next >
Text File  |  1997-07-01  |  17KB  |  702 lines

  1. {****************************************************************************
  2.  
  3.                         FPKPascal run time library
  4.                          Copyright (c) 1993,96 by
  5.                      Florian Klaempfl & Michael Spiegel
  6.  
  7.  ****************************************************************************}
  8.  
  9. {
  10.   history:
  11.   29th may 1994: version 1.0
  12.              unit is completed
  13.   14th june 1994: version 1.01
  14.              the address from which startaddr was read wasn't right; fixed
  15.   18th august 1994: version 1.1
  16.              the upper left corner of winmin is now 0,0
  17.   19th september 1994: version 1.11
  18.              keypressed handles extended keycodes false; fixed
  19.   27th february 1995: version 1.12
  20.              * crtinoutfunc didn't the line wrap in the right way;
  21.                fixed
  22.   20th january 1996: version 1.13
  23.              - unused variables removed
  24.   21th august 1996: version 1.14
  25.              * adapted to newer FPKPascal versions
  26.              * make the comments english
  27.    6th november 1996: version 1.49
  28.              * some stuff for DPMI adapted
  29.   15th november 1996: version 1.5
  30.              * bug in screenrows fixed
  31. }
  32.  
  33. unit crt;
  34.  
  35.   interface
  36.   
  37.     uses
  38.        go32;
  39.  
  40.     const
  41.        { screen modes }
  42.        bw40 = 0;
  43.        co40 = 1;
  44.        bw80 = 2;
  45.        co80 = 3;
  46.        mono = 7;
  47.        font8x8 = 256;
  48.  
  49.        { screen color, fore- and background }
  50.        black = 0;
  51.        blue = 1;
  52.        green = 2;
  53.        cyan = 3;
  54.        red = 4;
  55.        magenta = 5;
  56.        brown = 6;
  57.        lightgray = 7;
  58.  
  59.        { only foreground }
  60.        darkgray = 8;
  61.        lightblue = 9;
  62.        lightgreen = 10;
  63.        lightcyan = 11;
  64.        lightred = 12;
  65.        lightmagenta = 13;
  66.        yellow = 14;
  67.        white = 15;
  68.  
  69.        { blink flag }
  70.        blink = $80;
  71.  
  72.     var
  73.        { for compatibility }
  74.        checkbreak,checkeof,checksnow : boolean;
  75.  
  76.        { wenn true, wird von screeensetcursor die Graphikkarte }
  77.        { direkt programmiert                                   }
  78.        directvideo : boolean;
  79.  
  80.        lastmode : word; { screen mode}
  81.        textattr : byte; { current text attribute }
  82.        windmin : word; { Rechte obere Ecke des definierten Fensters }
  83.        windmax : word; { Linke untere Ecke des definierten Fensters }
  84.  
  85.     function keypressed : boolean;
  86.     function readkey : char;
  87.     procedure gotoxy(x,y : byte);
  88.     procedure window(left,top,right,bottom : byte);
  89.     procedure clrscr;
  90.     procedure textcolor(color : byte);
  91.     procedure textbackground(color : byte);
  92.     procedure assigncrt(var f : text);
  93.     function wherex : byte;
  94.     function wherey : byte;
  95.     procedure delline;
  96.     procedure delline(line : byte);
  97.     procedure clreol;
  98.     procedure insline;
  99.     procedure cursoron;
  100.     procedure cursoroff;
  101.     procedure cursorbig;
  102.     procedure lowvideo;
  103.     procedure highvideo;
  104.     procedure nosound;
  105.     procedure sound(hz : word);
  106.     procedure delay(ms : longint);
  107.     procedure textmode(mode : integer);
  108.     procedure normvideo;
  109.     
  110.   implementation
  111.   
  112.     var
  113.        maxcols,maxrows : longint;
  114.   
  115.     type
  116.        pword = ^word;
  117.         
  118.        textbuf = array[0..127] of char;
  119.  
  120.        textrec = record
  121.           handle : word;
  122.           mode : word;
  123.           bufSize : word;
  124.           { private : word; PRIVATE is keyword of FPKPascal }
  125.           _private : word;
  126.           bufpos : word;
  127.           bufend : word;
  128.           bufptr : ^textbuf;
  129.           openfunc : pointer;
  130.           inoutfunc : pointer;
  131.           flushfunc : pointer;
  132.           closefunc : pointer;
  133.           userdata : array[1..16] of byte;
  134.           name : string[79];
  135.           buffer : textbuf;
  136.        end;
  137.        
  138.     { includes low level routines }
  139.  
  140.     {$i modes.inc}
  141.  
  142.     function screenrows : byte;
  143.  
  144.       begin
  145.          dosmemget($40,$84,screenrows,1);
  146.          { don't forget this: }
  147.          inc(screenrows);
  148.       end;
  149.  
  150.     function screencols : byte;
  151.  
  152.       begin
  153.          dosmemget($40,$4a,screencols,1);
  154.       end;
  155.       
  156.     function get_addr(row,col : byte) : word;
  157.     
  158.       begin
  159.          get_addr:=((row-1)*maxcols+(col-1))*2;
  160.       end;
  161.  
  162.     procedure screensetcursor(row,col : longint);
  163.  
  164.       var
  165.          cols : byte;
  166.          pos : word;
  167.          regs : trealregs;
  168.       begin
  169.          if directvideo then
  170.            begin
  171.               { set new position for the BIOS }
  172.               dosmemput($40,$51,row,1);
  173.               dosmemput($40,$50,col,1);
  174.  
  175.               { calculates screen position }
  176.               dosmemget($40,$4a,cols,1);              
  177.               { FPKPascal calculates with 32 bit }
  178.               pos:=row*cols+col;
  179.  
  180.               { direct access to the graphics card registers }
  181.               outportb($3d4,$0e);
  182.               outportb($3d5,hi(pos)); 
  183.               outportb($3d4,$0f);
  184.               outportb($3d5,lo(pos)); 
  185.            end
  186.          else
  187. {            asm
  188.                movb     $0x02,%ah
  189.                movb     $0,%bh
  190.                movb     row,%dh
  191.                movb     col,%dl
  192.                pushl    %ebp
  193.                int      $0x10
  194.                popl     %ebp
  195.             end;}
  196.             regs.realeax:=$0200;
  197.             regs.realebx:=0;
  198.             regs.realedx:=row*$100+col;
  199.             realintr($10,regs);
  200.        end;
  201.  
  202.     procedure screengetcursor(var row,col : longint);
  203.  
  204.       begin
  205.          col:=0;
  206.          row:=0;
  207.          dosmemget($40,$50,col,1);
  208.          dosmemget($40,$51,row,1);
  209.       end;
  210.  
  211.     { exported routines }
  212.  
  213.     procedure cursoron;
  214.  
  215.     var     regs : trealregs;
  216.       begin
  217. {         asm
  218.             movb   $1,%ah
  219.             movb   $10,%cl
  220.             movb   $9,%ch
  221.             pushl %ebp
  222.             int   $0x10
  223.             popl %ebp
  224.          end;}
  225.             regs.realeax:=$0100;
  226.             regs.realecx:=$90A;
  227.             realintr($10,regs);
  228.          
  229.       end;
  230.    
  231.     procedure cursoroff;
  232.     
  233.     var     regs : trealregs;
  234.       begin
  235.             regs.realeax:=$0100;
  236.             regs.realecx:=$ffff;
  237.             realintr($10,regs);
  238. {        asm
  239.             movb   $1,%ah
  240.             movb   $-1,%cl
  241.             movb   $-1,%ch
  242.             pushl %ebp
  243.             int   $0x10
  244.             popl %ebp
  245.          end;}
  246.       end;
  247.    
  248.     procedure cursorbig;
  249.    
  250.     var     regs : trealregs;
  251.       begin
  252.             regs.realeax:=$0100;
  253.             regs.realecx:=$10A;
  254.             realintr($10,regs);
  255. {       begin
  256.          asm
  257.             movb   $1,%ah
  258.             movb   $10,%cl
  259.             movb   $1,%ch
  260.             pushl %ebp
  261.             int   $0x10
  262.             popl %ebp
  263.          end;}
  264.       end;
  265.       
  266.     var
  267.        is_last : boolean;
  268.        last : char;
  269.  
  270.     function readkey : char;
  271.  
  272.       var
  273.          char2 : char;
  274.          char1 : char;
  275.     var     regs : trealregs;
  276.  
  277.       begin
  278.          if is_last then
  279.            begin
  280.               is_last:=false;
  281.               readkey:=last;
  282.            end
  283.          else
  284.            begin
  285.             regs.realeax:=$0000;
  286.             realintr($16,regs);
  287.             byte(char1):=regs.realeax and $ff;
  288.             byte(char2):=(regs.realeax and $ff00) div $100;
  289. {              asm
  290.                  movb $0,%ah
  291.                  pushl %ebp
  292.                  int $0x16
  293.                  popl %ebp
  294.                  movw %ax,-2(%ebp)
  295.               end;}
  296.               if char1=#0 then
  297.                 begin
  298.                    is_last:=true;
  299.                    last:=char2;
  300.                 end;
  301.               readkey:=char1;
  302.            end;
  303.       end;
  304.  
  305.     function keypressed : boolean;
  306.    var regs : trealregs;
  307.       begin
  308.          if is_last then
  309.            begin
  310.               keypressed:=true;
  311.               exit;
  312.            end
  313.          else
  314.          begin
  315.             regs.realeax:=$0100;
  316.             realintr($16,regs);
  317.             if (regs.realflags and zeroflag) <> 0 then
  318.               keypressed:=true
  319.               else keypressed:=false;
  320.          end;
  321. {           asm
  322.               movb $1,%ah
  323.               pushl %ebp
  324.               int $0x16
  325.               popl %ebp
  326.               setnz %al
  327.               movb %al,__RESULT
  328.            end;}
  329.       end;
  330.  
  331.    procedure gotoxy(x,y : byte);
  332.  
  333.      begin
  334.         if (x<1) then
  335.           x:=1;
  336.         if (y<1) then
  337.           y:=1;
  338.         if y+hi(windmin)-2>=hi(windmax) then
  339.           y:=hi(windmax)-hi(windmin)+1;
  340.         if x+lo(windmin)-2>=lo(windmax) then
  341.           x:=lo(windmax)-lo(windmin)+1;
  342.         screensetcursor(y+hi(windmin)-1,x+lo(windmin)-1);
  343.      end;
  344.  
  345.    function wherex : byte;
  346.  
  347.      var
  348.         row,col : longint;
  349.  
  350.      begin
  351.         screengetcursor(row,col);
  352.         wherex:=col-lo(windmin)+1;
  353.      end;
  354.  
  355.    function wherey : byte;
  356.  
  357.      var
  358.         row,col : longint;
  359.  
  360.      begin
  361.         screengetcursor(row,col);
  362.         wherey:=row-hi(windmin)+1;
  363.      end;
  364.  
  365.    procedure window(left,top,right,bottom : byte);
  366.  
  367.      begin
  368.         if (left<1) or
  369.            (right>screencols) or
  370.            (bottom>screenrows) or
  371.            (left>right) or
  372.            (top>bottom) then
  373.            exit;
  374.         windmin:=(left-1) or ((top-1) shl 8);
  375.         windmax:=(right-1) or ((bottom-1) shl 8);
  376.         gotoxy(1,1);
  377.      end;
  378.  
  379.    procedure clrscr;
  380.  
  381.      var
  382.         fil : word;
  383.         row : longint;
  384.  
  385.      begin
  386.         fil:=32 or (textattr shl 8);
  387.         for row:=hi(windmin) to hi(windmax) do
  388.           dosmemfillword($b800,get_addr(row+1,lo(windmin)+1),lo(windmax)-lo(windmin)+1,fil);
  389.         gotoxy(1,1);
  390.      end;
  391.  
  392.    procedure textcolor(color : Byte);
  393.  
  394.      begin
  395.         textattr:=(textattr and $70) or color;
  396.      end;
  397.  
  398.    procedure lowvideo;
  399.  
  400.      begin
  401.         textattr:=textattr and $f7;
  402.      end;
  403.  
  404.    procedure highvideo;
  405.  
  406.      begin
  407.         textattr:=textattr or $08;
  408.      end;
  409.  
  410.    procedure textbackground(color : Byte);
  411.  
  412.      begin
  413.         textattr:=(textattr and $8f) or ((color and $7) shl 4);
  414.      end;
  415.  
  416.    var
  417.       startattrib : byte;
  418.  
  419.    procedure normvideo;
  420.  
  421.      begin
  422.         textattr:=startattrib;
  423.      end;
  424.  
  425.    procedure delline(line : byte);
  426.  
  427.      var
  428.         row,left,right,bot : longint;
  429.         fil : word;
  430.  
  431.      begin
  432.         row:=line+hi(windmin);
  433.         left:=lo(windmin)+1;
  434.         right:=lo(windmax)+1;
  435.         bot:=hi(windmax)+1;
  436.         fil:=32 or (textattr shl 8);
  437.         while (row<bot) do
  438.           begin
  439.              dosmemmove($b800,get_addr(row+1,left),$b800,get_addr(row,left),(right-left+1)*2);
  440.              inc(row);
  441.           end;
  442.         dosmemfillword($b800,get_addr(bot,left),right-left+1,fil);
  443.      end;
  444.  
  445.    procedure delline;
  446.  
  447.      begin
  448.         delline(wherey);
  449.      end;
  450.  
  451.    procedure insline;
  452.  
  453.      var
  454.         row,col,left,right,bot : longint;
  455.         fil : word;
  456.  
  457.      begin
  458.         screengetcursor(row,col);
  459.         inc(row);
  460.         left:=lo(windmin)+1;
  461.         right:=lo(windmax)+1;
  462.         bot:=hi(windmax);
  463.         fil:=32 or (textattr shl 8);
  464.         while (bot>row) do
  465.           begin
  466.              dosmemmove($b800,get_addr(bot-1,left),$b800,get_addr(bot,left),(right-left+1)*2);
  467.              dec(bot);
  468.           end;
  469.         dosmemfillword($b800,get_addr(row,left),right-left+1,fil);
  470.      end;
  471.  
  472.    procedure clreol;
  473.  
  474.      var
  475.         row,col : longint;
  476.         fil : word;
  477.  
  478.      begin
  479.         screengetcursor(row,col);
  480.         inc(row);
  481.         inc(col);
  482.         fil:=32 or (textattr shl 8);
  483.         dosmemfillword($b800,get_addr(row,col),lo(windmax)-col+2,fil);
  484.      end;
  485.  
  486.    procedure crtinoutfunc(var f : textrec);
  487.  
  488.       var
  489.          i,col,row : longint;
  490.          c : char;
  491.          va,sa : word;
  492.  
  493.       begin
  494.          screengetcursor(row,col);
  495.          inc(row);
  496.          inc(col);
  497.          va:=get_addr(row,col);
  498.          if f.mode=fmoutput then
  499.            begin
  500.               for i:=0 to f.bufpos-1 do
  501.                 begin
  502.                    c:=f.buffer[i];
  503.                    case ord(c) of
  504.                       10 : begin
  505.                               inc(row);
  506.                               va:=va+maxcols*2;
  507.                            end;
  508.                       13 : begin
  509.                               col:=lo(windmin)+1;
  510.                               va:=get_addr(row,col);
  511.                           end;
  512.                       8 : if col>lo(windmin)+1 then
  513.                             begin
  514.                                dec(col);
  515.                                va:=va-2;
  516.                             end;
  517.                       7 : begin
  518.                               { beep }
  519.                            end;
  520.                    else
  521.                       begin
  522.                          sa:=textattr shl 8 or ord(c);
  523.                          dosmemput($b800,va,sa,sizeof(sa));
  524.                          inc(col);
  525.                          va:=va+2;
  526.                       end;
  527.                    end;
  528.                    if col>lo(windmax)+1 then
  529.                      begin
  530.                         col:=lo(windmin)+1;
  531.                         inc(row);
  532.  
  533.                         { it's easier to calculate the new address }
  534.                         { it don't spend much time                 }
  535.                         va:=get_addr(row,col);
  536.                      end;
  537.                    while row>hi(windmax)+1 do
  538.                      begin
  539.                         delline(1);
  540.                         dec(row);
  541.                         va:=va-maxcols*2;
  542.                      end;
  543.                 end;
  544.               f.bufpos:=0;
  545.               screensetcursor(row-1,col-1);
  546.            end
  547.          {!!!!!!}
  548.          else halt(100);
  549.       end;
  550.  
  551.    procedure assigncrt(var f : text);
  552.  
  553.      begin
  554.         textrec(f).inoutfunc:=@crtinoutfunc;
  555.         textrec(f).flushfunc:=@crtinoutfunc;
  556.      end;
  557.  
  558.    procedure sound(hz : word);
  559.  
  560.      begin
  561.         if hz=0 then
  562.           begin
  563.              nosound;
  564.              exit;
  565.           end;
  566.         asm
  567.            movzwl hz,%ecx
  568.            movl $1193046,%eax
  569.        cdq
  570.            divl %ecx
  571.            movl %eax,%ecx
  572.            movb $0xb6,%al
  573.            outb %al,$0x43
  574.            movb %cl,%al
  575.            outb %al,$0x42
  576.            movb %ch,%al
  577.            outb %al,$0x42
  578.            inb $0x61,%al
  579.            orb $0x3,%al
  580.            outb %al,$0x61
  581.         end ['EAX','ECX','EDX'];
  582.      end;
  583.  
  584.    procedure nosound;
  585.  
  586.      begin
  587.         asm
  588.            inb $0x61,%al
  589.            andb $0xfc,%al
  590.            outb %al,$0x61
  591.         end ['EAX'];
  592.      end;
  593.  
  594.    var
  595.       calibration : longint;
  596.  
  597.    procedure delay(ms : longint);
  598.  
  599.       var
  600.          i,j : longint;
  601.  
  602.      begin
  603.         for i:=1 to ms do
  604.           for j:=1 to calibration do
  605.              begin
  606.              end;
  607.      end;
  608.  
  609.   function get_ticks : word;
  610.  
  611.     begin
  612.        dosmemget($40,$6c,get_ticks,2);
  613.     end;
  614.  
  615.   procedure initdelay;
  616.  
  617.     var
  618.        first : word;
  619.  
  620.     begin
  621.        calibration:=0;
  622.  
  623.        { wait for new tick }
  624.        first:=get_ticks;
  625.        while get_ticks=first do
  626.          begin
  627.          end;
  628.        first:=get_ticks;
  629.  
  630.        { this estimates calibration }
  631.        while get_ticks=first do
  632.          inc(calibration);
  633.  
  634.        { calculate this to ms }
  635.        calibration:=calibration div 70;
  636.        while true do
  637.          begin
  638.             first:=get_ticks;
  639.             while get_ticks=first do
  640.               begin
  641.               end;
  642.             first:=get_ticks;
  643.             delay(55);
  644.             if first=get_ticks then
  645.                exit
  646.             else begin
  647.                     { decrement calibration two percent }
  648.                     calibration:=calibration-calibration div 50;
  649.                     dec(calibration);
  650.                  end;
  651.          end;
  652.     end;
  653.  
  654.   procedure textmode(mode : integer);
  655.  
  656.     var
  657.        set_font8x8 : boolean;
  658.  
  659.     begin
  660.        lastmode:=mode;
  661.        set_font8x8:=(mode and font8x8)<>0;
  662.        mode:=mode and $ff;
  663.        setscreenmode(mode);
  664.        windmin:=0;
  665.        windmax:=(screencols-1) or ((screenrows-1) shl 8);
  666.        maxcols:=screencols;
  667.        maxrows:=screenrows;
  668.     end;
  669.  
  670. var
  671.    col,row : longint;
  672.  
  673. begin
  674.    is_last:=false;
  675.  
  676.    { direct access to graphics card registers }
  677.    { direct video generates a GPF in DPMI 
  678.    of setcursor }
  679.    directvideo:=false;
  680.  
  681.    { set output window }
  682.    windmin:=0;
  683.    windmax:=(screencols-1) or ((screenrows-1) shl 8);
  684.  
  685.    { load system variables to temporary variables to save time }
  686.    maxcols:=screencols;
  687.    maxrows:=screenrows;
  688.  
  689.    { save the current settings to restore the old state after the exit }
  690.    screengetcursor(row,col);
  691.    dosmemget($b800,get_addr(row+1,col+1)+1,startattrib,1);
  692.    lastmode:=getscreenmode;
  693.    textattr:=startattrib;
  694.  
  695.    { redirect the standard output }
  696.    assigncrt(output);
  697.  
  698.    { calculates delay calibration }
  699. {   initdelay; }
  700. end.
  701.  
  702.